#include "SkySphereBackground.cuh"

using namespace OBR;

extern "C" __global__ void __miss__sky_sphere_background()
{
    SamplePRD *prd = getPRD();
    prd->hit = false;
    prd->inter.wi.t = prd->inter.wi.tmax;

    if (prd->ray_occlusion_test)
    {
        return;
    }

#ifdef DEBUG_SHADER
    if (prd->log)
    {
        printf("skysphere miss program launched\n");
    }
#endif

    MissData *sbt_record = reinterpret_cast<MissData *>(optixGetSbtDataPointer());
    SkySphereBackgroundData *data =
        reinterpret_cast<SkySphereBackgroundData *>(sbt_record->background_payload);

    float3 ray = normalize(prd->inter.wi.d);
    float costheta = clamp(ray.x / sqrtf(1.0f - ray.z * ray.z), -1.0f, 1.0f);
    float sintheta = clamp(ray.y / sqrtf(1.0f - ray.z * ray.z), -1.0f, 1.0f);
    float theta = acosf(costheta);
    theta = (sintheta < 0) ? 2.0f * M_PIf - theta : theta;

    float2 uv;
    uv.x = theta * M_1_PIf * 0.5f;
    uv.y = (1.0f - ray.z) * 0.5f;
    prd->bg_radiance = data->bg.sample(uv, TextureSampleMode::XLINEAR);

#ifdef DEBUG_SHADER
    if (prd->log)
    {
        printf("uv: [%.6f, %.6f]\n", uv.x, uv.y);
        printf("texture size: %d * %d\n", data->bg.size.x, data->bg.size.y);
        printf("get bg radiance: ");
        prd->bg_radiance.print();
        printf("\n");
        printf("miss program ended\n");
    }
#endif
}